/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package computing;

import com.jme3.math.Vector3f;
import data.Grid3d;
import data.Vector3i;
import java.util.ArrayList;
import java.util.Set;
import java.util.HashSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import pointfinder.PointEntity;

/**
 *
 * @author oxplay
 */
public class ComputeBlindMove {

    private final static Logger logger = Logger.getLogger(ComputeBlindMove.class.getName());
    private ArrayList<Vector3f> waypoints = new ArrayList<Vector3f>();
    private Set<Vector3i> usedVectors = new HashSet<Vector3i>();
    private Grid3d grid;
    private Vector3i catchStart;
    private Vector3i catchEnd;
    private int tmpStartX, tmpStartY, tmpStartZ, tmpEndX, tmpEndY, tmpEndZ;
    private int x, y, z, actualX, actualY, actualZ, actualDistance, tmpDistance;
    private boolean isDone = false;
    public ComputeBlindMove(Grid3d grid, Vector3i catchStart, Vector3i catchEnd) {
        this.grid = grid;
        this.catchStart = catchStart;
        this.catchEnd = catchEnd;
        actualX = catchStart.x;
        actualY = catchStart.y;
        actualZ = catchStart.z;
        logger.setLevel(Level.WARNING);
    }

    public ArrayList<Vector3f> getWaypoints() {
        return waypoints;
    }

    public Vector3f getLastWaypoint() {
        if (waypoints.size() > 0) {
            return waypoints.get(waypoints.size() - 1);
        } else {
            return null;
        }
    }

    public void makeStep(int steps) {
        actualDistance = -1;
        tmpStartX = actualX - 1;
        tmpStartY = actualY - 1;
        tmpStartZ = actualZ - 1;
        tmpEndX = actualX + 1;
        tmpEndY = actualY + 1;
        tmpEndZ = actualZ + 1;
        for (x = tmpStartX; x <= tmpEndX; x++) {
            for (z = tmpStartZ; z <= tmpEndZ; z++) {
                for (y = tmpStartY; y <= tmpEndY; y++) {
                    tmpDistance = Math.abs(catchEnd.x - x) + Math.abs(catchEnd.y - y) + Math.abs(catchEnd.z - z);
                    logger.log(Level.INFO, "[{0},{1},{2}] tmpDistance: {3} actualDistance: {4}", new Object[]{x, y, z, tmpDistance, actualDistance});
                    if(actualDistance == -1 || tmpDistance < actualDistance){
                        if(grid.getGridPoint(new Vector3i(x,y,z)).equals(PointEntity.MOVEABLE)){
                            logger.log(Level.INFO, "setting");
                            actualDistance = tmpDistance;
                            actualX = x;
                            actualY = y;
                            actualZ = z;
                        }
                    }
                }
            }
        }
        Vector3i nextval = new Vector3i(actualX, actualY, actualZ);
        if(!usedVectors.contains(nextval)){
            usedVectors.add(nextval);
            waypoints.add(new Vector3i(actualX, actualY, actualZ).getVector3f());
            if(steps <= -1 || steps>0){
                makeStep(steps-1);
            }
        } else {
            isDone = true;
        }
    }

    public boolean isDone(){
        return isDone;
    }
    
    public void makeSteps(int stepsCount) {
        makeStep(stepsCount);
    }
    
    public void simulateMove() {
        makeStep(-1);
    }
}
